Для популяризации хоккея и повышения мастерства
хоккейных команд Урала был организован Всеуральский турнир. Для участия в
турнире были приглашены n хоккейных команд из городов Урала.
После первых двух туров, в каждом из которых каждая
команда провела по одному матчу, оказалось, что команд слишком много.
Организаторами турнира было решено допустить к дальнейшему участию только k команд, никакие две из которых не
встречались в рамках первых двух туров.
Требуется написать программу, которая находит набор из k команд,
удовлетворяющий условиям, либо выводит сообщение о том, что это сделать
невозможно. В случае существования нескольких подходящих наборов необходимо
найти любой из них.
Вход. В первой строке содержится число n (2 ≤ n ≤ 100000, n чётное). Следующие n строк содержат
описания всех прошедших матчей. Описание каждого матча состоит из двух
натуральных чисел, не превышающих n –
номеров команд, игравших в матче. Первые n / 2 из них соответствуют матчам первого тура, оставшиеся –
матчам второго тура. Последняя строка
содержит одно число k (2 ≤ k ≤ n).
Гарантируется, что каждая команда сыграла ровно два
матча: один в первом туре и один во втором.
Выход. Вывести
либо единственное число 0, если решения не существует, либо k различных чисел – номера отобранных
команд.
Пример входа 1 |
Пример выхода 1 |
6 1 2 3 5 4 6 2 3 4 5 1 6 3 |
1 4 3 |
|
|
Пример входа 2 |
Пример выхода 2 |
4 1 2 3 4 2 1 4 3 3 |
0 |
графы - циклы
Каждой хоккейной
команде поставим в соответствие вершину графа. Сыгранные игры – ребра графа.
Каждая команда провела в точности две игры. Степень каждой вершины графа равна
2, значит граф представляет собой набор простых циклов. В каждом цикле можно
выбрать вершины (номера команд) через одну. Они нам подходят, так как они еще
не играли между собой. Таким образом всегда можно выбрать не более n / 2 вершин. Следовательно
решение существует только при k ≤ n / 2.
После сыгранных
двух туров граф имеет вид одного цикла из 6 вершин.
Граф представляет собой два цикла. Тогда
отобранными могут быть команды 1, 3, 5 или 2, 4, 6.
Объявим список смежности графа g и рабочие массивы.
vector <vector <int> > g;
vector<int> used, res;
Поиск в глубину из вершины v. В массиве res запоминаем порядок обхода вершин.
void dfs(int v)
{
used[v] = 1;
res.push_back(v);
for (int i = 0; i < g[v].size(); i++)
{
int to = g[v][i];
if (used[to] == 0) dfs(to);
}
}
Основная часть программы. Читаем
входные данные. Строим граф.
scanf("%d", &n);
g.resize(n + 1);
for (i = 0; i < n; i++)
{
scanf("%d %d", &a,
&b);
g[a].push_back(b);
g[b].push_back(a);
}
scanf("%d", &k);
Граф может быть несвязным.
Запускаем поиск в глубину на несвязном графе.
used.resize(n + 1);
for (i = 1; i <= n; i++)
if (used[i] == 0) dfs(i);
В зависимости от значения k выводим ответ. Решение
существует только при k ≤ n / 2.
if (k <= n / 2)
{
for (i = 0; i < k; i++)
printf("%d
", res[2 * i]);
printf("\n");
}
else
puts("0");